#include <Wire.h>
#include <ADXL345.h>
#include "SSD1306Wire.h"

float MIN=1.1;
/* 我们的ESP8266小板的引脚是GPIO2和GPIO14，对应的是D4和D5 地址是0X3c */
SSD1306Wire display(0x3c, 2, 14); /* ADDRESS, SDA, SCL */
ADXL345 accel(ADXL345_ALT);       /* ADXL345 设置地址为 0x53 */

void show_ADXL_in_Serial(int delay_num);
void show_ADXL_in_SSD1306(int delay_num);
void show_ADXL_by_RGB(int delay_num);
String format_String(const char *format, float val); /* 临时设计的函数，需要每次都重新写实现细节 */
void RGB_INIT();
void RGB_SHOW(int r, int g, int b);
int trans_float_RGB(float a);
// int max_3(int a, int b, int c){if (a <= b)if (b <= c)return 3;elsereturn 2;elsereturn 1;}
int fall_detection(int delay_num);
void setup(void)
{
  Serial.begin(115200); /* 调试输出初始化 */
  display.init();       /* SSD1306初始化 */
  RGB_INIT();
  /* ADXL345 设定频率 */ /* 可选范围(HZ) 3200 1600 800 400 200 100 50 25 */
  if (!accel.writeRate(ADXL345_RATE_200HZ))
  {
    Serial.println("write rate: failed");
    while (1)
    {
      delay(1000);
    }
  }
  /* ADXL345 设定量程 */ /* 可选范围 2G 4G 8G 16G */
  if (!accel.writeRange(ADXL345_RANGE_4G))
  {
    Serial.println("write range: failed");
    while (1)
    {
      delay(1000);
    }
  }
}

void loop(void)
{
  fall_detection(10);
}
void show_ADXL_in_Serial(int delay_num)
{
  if (accel.update())
  {
    Serial.print("X:");
    Serial.print(accel.getX());
    Serial.print(",");
    Serial.print("Y:");
    Serial.print(accel.getY());
    Serial.print(",");
    Serial.print("Z:");
    Serial.print(accel.getZ());
    Serial.println("");
  }
  else
  {
    Serial.println("update failed");
  }
  delay(delay_num);
}
void show_ADXL_in_SSD1306(int delay_num)
{
  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_16);
  if (accel.update())
  {
    display.drawString(5, 5, format_String("X : %.2f", accel.getX()));
    display.drawString(5, 25, format_String("Y : %.2f", accel.getY()));
    display.drawString(5, 45, format_String("Z : %.2f", accel.getZ()));
  }
  else
  {
    display.drawString(0, 20, format_String(" Update Error", 0));
  }
  display.display();
  delay(delay_num);
}
String format_String(const char *format, float val)
{
  char ch[20];
  sprintf(ch, format, val);
  String out = "";
  for (int i = 0; ch[i] != '\0'; i++)
    out += ch[i];
  return out;
}
int trans_float_RGB(float a)
{
  int out = a >= 0 ? (int)(a * 100) : (int)(a * -100);
  return out >= 255 ? 255 : out;
}
void RGB_SHOW(int r, int g, int b)
{
  analogWrite(0, r);
  analogWrite(4, g);
  analogWrite(5, b);
  // switch (max_3(r,g,b)){case 1:analogWrite(0, 255);break;case 2:analogWrite(4, 255);break;case 3:analogWrite(5, 255);break;default:  break;}
  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_16);
  if ((r + g + b) != 0)
  {
    display.drawString(5, 5, format_String("R : %.0f", (float)r));
    display.drawString(5, 25, format_String("G : %.0f", (float)g));
    display.drawString(5, 45, format_String("B : %.0f", (float)b));
  }
  else
  {
    display.drawString(0, 20, format_String(">> ALL ZERO <<", 0));
  }
  display.display();
}
void RGB_INIT()
{
  pinMode(0, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  RGB_SHOW(0, 0, 0);
}
void show_ADXL_by_RGB(int delay_num)
{
  if (accel.update())
  {
    int ax = trans_float_RGB(accel.getX());
    int ay = trans_float_RGB(accel.getY());
    int az = trans_float_RGB(accel.getZ());
    RGB_SHOW(ax, ay, az);
  }
  else
  {
    RGB_SHOW(0, 0, 0);
  }
  delay(delay_num);
}
int fall_detection(int delay_num)
{
  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_16);
  if (accel.update())
  {
    float SUM = (accel.getX() * accel.getX()) + (accel.getY() * accel.getY()) + (accel.getZ() * accel.getZ());
    MIN = 9;
    MIN = SUM <= MIN ? SUM : MIN;
    display.drawString(0, 15, format_String("SUM: %.3f", SUM));
    display.drawString(0, 35, format_String("MIN: %.3f", MIN));
  }
  else
  {
    display.drawString(0, 20, format_String(" Update Error", 0));
  }
  display.display();
  delay(delay_num);
}